/**
 在文章最开始，先学习几个概念：

作用域：《你不知道的js》中指出，作用域是一套规则，这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找。
简单来说，作用域规定了如何查找变量。
作用域规定了如何查找变量，也就是确定当前执行代码对变量的访问权限。
JavaScript 采用词法作用域(lexical scoping)，也就是静态作用域。


// JavaScript采用的是词法作用域，函数定义的位置就决定了函数的作用域。
var val = 1;
function test() {
    console.log(val);
}
function bar() {
    var val = 2;
    test();
}

bar();
/***
 * 静态作用域执行过程
 当函数执行test函数时，先从内部的AO对象查找是否有val对象，
 如果没有，沿着作用域链往上查找(由于JavaScript是词法作用域)，上层为全局GO，所以结果打印1

 * 动态作用域执行过程
但如果JavaScript采用的动态作用域，执行test函数，从函数内部查询val变量，
如果没有，就调用函数的作用域，即bar函数的作用域，成功查询到val=2
那什么语言是动态语言，请运行 04.scope.bash -> bash ./04.scope.bash 
 */

// 2--------------------
console.log("2--------------------")
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
console.log(checkscope());

// 3--------------------
console.log("3--------------------")
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
console.log(checkscope()())
/**
 很明显，两个都打印local scope，JavaScript采用词法作用域，上述两个函数都定义在checkscope中，
 所以当f()函数执行时，首先查询自身作用域是否有scope变量，如果没有，它们的上级作用域都是checkscope，所以输出local scope。

对此《JavaScript权威指南》解释到：JavaScript 函数的执行用到了作用域链，这个作用域链是在函数定义的时候创建的。
嵌套的函数 f() 定义在这个作用域链里，
其中的变量 scope 一定是局部变量，不管何时何地执行函数 f()，这种绑定在执行 f() 时依然有效。
 */
